/*
 * @Author: soso
 * @Date: 2022-02-15 02:00:03
 * @LastEditTime: 2022-02-17 15:42:57
 * @LastEditors: Please set LastEditors
 * @Description: 归档工具
 * @FilePath: /gomeshsync/core/cfiles/arch.go
 */
package cfiles

import (
	"gomeshsync/core/scmd"
	"strconv"
	"sync"
	"time"

	"gitee.com/kimsoso/go-utils/revfile"
	"github.com/vmihailenco/msgpack/v5"
)

type arch struct {
	rfile revfile.Revfile           //磁盘文件
	cmds  map[string]*scmd.MCommand //缓存
	from  int                       //缓存位置
}

var (
	onceArch      sync.Once
	archSingleton *arch
)

func NewArch() *arch {
	onceArch.Do(func() {
		archSingleton = &arch{
			rfile: revfile.NewRevFile(PathOfArch),
			cmds:  map[string]*scmd.MCommand{},
			from:  -1,
		}
	})
	return archSingleton
}

// 清除缓存
func (ar *arch) clearCache() {
	ar.from = -1
	ar.cmds = map[string]*scmd.MCommand{}
}

// 读取命令
func (ar *arch) GetCmds(from int) (out map[string]*scmd.MCommand) {
	if ar.from == from {
		return ar.cmds
	}

	ar.from = from
	out = map[string]*scmd.MCommand{}
	ar.rfile.Read(func(data []byte) bool {
		cmds := []*scmd.MCommand{}
		msgpack.Unmarshal(data, &cmds)

		for _, cmd := range cmds {
			if cmd.Ck >= from {
				k := strconv.Itoa(cmd.Ck)

				out[k] = cmd
				ar.cmds[k] = cmd

				return true
			} else {
				return false
			}
		}
		return false
	})
	return
}

// 归档命令
func (ar *arch) ArchiveCmds() {
	endTime := time.Now().Add(-time.Minute * 30)
	endTimeUnix := endTime.Unix()

	cmds := _CMDS.cmds.GetBlocks()
	backupCmds := []*scmd.MCommand{}

	for k, cmd := range cmds {
		if cmd.Done && cmd.CreateTime <= endTimeUnix {
			backupCmds = append(backupCmds, cmd)
			_CMDS.cmds.Delete(k)
		}
	}

	if len(backupCmds) == 0 {
		return
	}

	ar.clearCache()

	buf, _ := msgpack.Marshal(backupCmds)
	ar.rfile.Append([][]byte{buf})
}
